﻿using System;
using System.Globalization;
using System.Linq;
using System.Reflection;
using System.Windows.Data;

namespace BrasilFramework.Comum.WPF.Utilitario
{

    /// <summary>
    /// Converte o Objeto em Texto no seguinte formato: "Separador :{NomePropriedadeA, NomePropriedadeB}"
    /// </summary>
    public class ConversorObjetoTexto : IValueConverter
    {
        #region IValueConverter Members

        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            if (value == null || parameter == null) return value;

            string parametro = parameter.ToString();

            //[0] - Separador entre as propriedades. Ex.: PropriedadeA + Separador + Propriedade2.
            string separador;
            string[] propriedades;

            try
            {
                string[] listaParametro = parametro.Split(':');
                separador = listaParametro[0];
                propriedades = listaParametro[1].Trim().Substring(1, listaParametro[1].Length - 2).Split(',');
            }
            catch (Exception)
            {
                throw new FormatException("Parâmetros inválidos. Ex.: Separador :{NomePropriedadeA, NomePropriedadeB} ");
            }

            string retorno = propriedades.Select(t => PegarValor(value, t.Trim())).Where(valor => valor != null).Aggregate(string.Empty, (current, valor) => current + (valor + separador));

            return retorno.TrimEnd(separador.ToCharArray());
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }

        #endregion

        /// <summary>
        /// Atribui um valor à uma propriedade em um objeto
        /// </summary>
        /// <param name="objeto">Objeto</param>
        /// <param name="propriedade">Nome da propriedade</param>
        private static object PegarValor(object objeto, string propriedade)
        {
            int idx = propriedade.IndexOf('.');
            if (idx > 0)
            {
                PropertyInfo property = objeto.GetType().GetProperty(propriedade.Remove(idx));
                return PegarValor(property.GetValue(objeto, null), propriedade.Substring(idx + 1));
            }

            object valor = objeto.GetType().GetProperty(propriedade).GetValue(objeto, null);

            if (valor != null && valor.GetType() == typeof(DateTime))
                return ((DateTime) valor).ToString("dd/MM/yyyy");

            return objeto.GetType().GetProperty(propriedade).GetValue(objeto, null);
        }
    }
}